package conlon.rocketmq.mq.listen;

import conlon.rocketmq.service.I8tLocalTransactionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author conlon
 */
@Component(value = "transactionListen01")
@Slf4j
public class TransactionListen01 implements TransactionListener {


    @Autowired
    private I8tLocalTransactionService i8tLocalTransactionService;

    /**
     * 当发送半消息成功时，我们使用 executeLocalTransaction 方法来执行本地事务 , 它返回前一节中提到的三个事务状态之一
     * 实测发现 该回调 和 transactionMqProducer.sendMessageInTransaction 是在同一个线程当中的
     * 那么在这个回查当中必然会阻塞运行之前的数据 。(这个我还需要在思考一下)
     **/
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        if (i8tLocalTransactionService.createI8tTransaction(msg)){
            log.info("TransactionListen-executeLocalTransaction-COMMIT_MESSAGE 01");
            return LocalTransactionState.COMMIT_MESSAGE;
        }
        return LocalTransactionState.UNKNOW;
    }

    /**
     * checkLocalTransaction 方法用于检查本地事务状态，并回应消息队列的检查请求。它也是返回前一节中提到的三个事务状态之一。
     * 为了避免单个消息被检查太多次而导致半队列消息累积，我们默认将单个消息的检查次数限制为 15 次，但是用户可以通过 Broker 配置文件的 transactionCheckMax参数来修改此限制
     * 当前回调已经不再是 和发送在同一个线程当中了 。 是由mq发起的回查
     **/
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        if (i8tLocalTransactionService.getUniqKey(msg.getTransactionId())){
            return LocalTransactionState.COMMIT_MESSAGE;
        }else {
            return LocalTransactionState.UNKNOW;
        }
    }
}

